home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacWT 0.9 / wt Source / slice.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-18  |  8.7 KB  |  444 lines  |  [TEXT/CWIE]

  1. /*
  2. **  MacWT -- a 3d game engine for the Macintosh
  3. **  © 1995, Bill Hayden and Nikol Software
  4. **
  5. **  On the Internet:
  6. **  bmoc1@aol.com (my personal address)
  7. **  nikolsw@grove.ufl.edu (my school address)
  8. **    MacWT anonymous FTP site: ftp.circa.ufl.edu/pub/software/ufmug/mirrors/LocalSW/Hayden/
  9. **  http://grove.ufl.edu:80/~nikolsw (my WWW page, containing MacWT info)
  10. **
  11. **  based on wt, by Chris Laurel (claurel@mr.net)
  12. **
  13. **  This program is distributed in the hope that it will be useful,
  14. **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16. */
  17.  
  18.  
  19.  
  20. #define PIXEL_GUARD_VAL ((Pixel) ~0)
  21.  
  22. #define PIXEL_CYAN16    ((Pixel16) 0x001F)
  23. #define PIXEL_CYAN        ((Pixel) 0xD2)
  24.  
  25.  
  26. inline void draw_wall_slice(Pixel *start, Pixel *end, Pixel *tex_base,
  27.                 fixed tex_y, fixed tex_dy, int fb_width, int baseshift);
  28.  
  29. inline void draw_floor_slice(Pixel *start, Pixel *tex,
  30.                  fixed x, fixed y, fixed dx, fixed dy,
  31.                  short tex_width, short npix);
  32.  
  33. inline void draw_transparent_slice(Pixel *start, Pixel *end, Pixel *tex_base,
  34.                 fixed tex_y, fixed tex_dy, int fb_width, 
  35.                 int tex_height);
  36.  
  37.  
  38. inline void draw_wall_slice16(Pixel16 *start, Pixel16 *end, Pixel16 *tex_base,
  39.                 fixed tex_y, fixed tex_dy, int fb_width, int baseshift);
  40.  
  41. inline void draw_floor_slice16(Pixel16 *start, Pixel16 *tex,
  42.                  fixed x, fixed y, fixed dx, fixed dy,
  43.                  short tex_width, short npix);
  44.  
  45. inline void draw_transparent_slice16(Pixel16 *start, Pixel16 *end, Pixel16 *tex_base,
  46.                 fixed tex_y, fixed tex_dy, int fb_width, 
  47.                 int tex_height);
  48.  
  49.  
  50.  
  51. /*****************************************************************/
  52.  
  53.  
  54.  
  55. inline void draw_wall_slice(Pixel *start, Pixel *end, Pixel *tex_base,
  56.                             fixed tex_y, fixed tex_dy, int fb_width, 
  57.                             int baseshift)
  58. {
  59.     unsigned int utex_y;
  60.  
  61.     utex_y = (unsigned int) tex_y;
  62.  
  63.  
  64.     if (baseshift == 10)    // (2^(16-10), or 2^6, or 64 pixels)
  65.         {
  66.         utex_y <<= 10;
  67.         tex_dy <<= 10;
  68.  
  69.         while (start >= end)
  70.             {
  71.             *start = tex_base[utex_y >> 26];
  72.             utex_y += tex_dy;
  73.             start -= fb_width;
  74.             }
  75.         }
  76.     else if (baseshift == 9)    // (2^(16-9), or 2^7, or 128 pixels)
  77.         {
  78.         utex_y <<= 9;
  79.         tex_dy <<= 9;
  80.  
  81.         while (start >= end)
  82.             {
  83.             *start = tex_base[utex_y >> 25];
  84.             utex_y += tex_dy;
  85.             start -= fb_width;
  86.             }
  87.         }
  88.     else    // General (but slower) routine to handle any other power-of-2 texture size
  89.         {
  90.         utex_y <<= baseshift;
  91.         tex_dy <<= baseshift;
  92.         baseshift += 16;
  93.  
  94.         while (start >= end)
  95.             {
  96.             *start = tex_base[utex_y >> baseshift];
  97.             utex_y += tex_dy;
  98.             start -= fb_width;
  99.             }
  100.         }
  101. }
  102.  
  103.  
  104.  
  105.  
  106. inline void draw_floor_slice(Pixel *start, Pixel *tex,
  107.                  fixed x, fixed y, fixed dx, fixed dy,
  108.                  short log2_tex_height, short npix)
  109. {
  110.     register Pixel temp;
  111.  
  112.  
  113.     if (log2_tex_height == 6)
  114.         {
  115.         /* width of 64 == 2^6 */
  116.         y <<= 6;
  117.         dy <<= 6;
  118.  
  119.         do {
  120.             x &= 0x3fffff;
  121.  
  122.            // No need to mask y--it rolls automatically *if* ints are 32 bits.
  123.            
  124.             if (*start == PIXEL_CYAN)
  125.                 {
  126.                 temp = tex[FIXED_TO_INT((y & 0xfc00000) | x)];
  127.                 *start++ = temp;
  128.                 }
  129.             else
  130.                 *start++;
  131.             x += dx;
  132.             y += dy;
  133.             }
  134.         while (--npix > 0);
  135.         }
  136.     else if (log2_tex_height == 7)
  137.         {
  138.         y <<= 7;
  139.         dy <<= 7;
  140.  
  141.         do {
  142.             x &= 0x7fffff;
  143.  
  144.             if (*start == PIXEL_CYAN)
  145.                 {
  146.                 temp = tex[FIXED_TO_INT((y & 0x3f800000) | x)];
  147.                 *start++ = temp;
  148.                 }
  149.             else
  150.                 *start++;
  151.             x += dx;
  152.             y += dy;
  153.             }
  154.         while (--npix > 0);
  155.         }
  156.     else    // General (but slower) routine to handle any other power-of-2 texture size
  157.         {
  158.         do {
  159.             x &= 0xffffffff >> (16 - log2_tex_height);
  160.             x &= 0x3fffff;
  161.  
  162.             /* No need to mask y--it rolls automatically *if* ints
  163.             **   are 32 bits.
  164.             */
  165.         
  166.             if (*start == PIXEL_CYAN)
  167.                 {
  168.                 temp = tex[FIXED_TO_INT((y & (((1<<log2_tex_height)-1) <<(log2_tex_height+16))) | x)];
  169.                 *start++ = temp;
  170.                 }
  171.             else
  172.                 *start++;
  173.  
  174.             x += dx;
  175.             y += dy;
  176.             }
  177.         while (--npix > 0);
  178.         }
  179.  
  180. }
  181.  
  182.  
  183.  
  184.  
  185. inline void draw_transparent_slice(Pixel *start, Pixel *end, Pixel *tex_base,
  186.                                 fixed tex_y, fixed tex_dy, int fb_width, int baseshift)
  187. {
  188.     unsigned int utex_y;
  189.     Pixel p;
  190.  
  191.  
  192.      /* As a speed optimization, tex_y and tex_dy are shifted left by several
  193.      **   bits so that tex_y can overflow correctly without explicit
  194.      **   and-masking.  For this to occur correctly, it is necessary to
  195.      **   make utex_y an unsigned quantity.  This is probably non-portable,
  196.      **   but should work with most architectures.
  197.      */
  198.     utex_y = (unsigned int) tex_y;
  199.  
  200.  
  201.     if (baseshift == 10)
  202.         {
  203.         utex_y <<= 10;
  204.         tex_dy <<= 10;
  205.  
  206.         while (start >= end)
  207.             {
  208.             p = tex_base[utex_y >> 26];
  209.             if (p != PIXEL_CYAN)
  210.                 *start = p;
  211.             utex_y += tex_dy;
  212.             start -= fb_width;
  213.             }
  214.         }
  215.     else if (baseshift == 9)
  216.         {
  217.         utex_y <<= 9;
  218.         tex_dy <<= 9;
  219.  
  220.         while (start >= end)
  221.             {
  222.             p = tex_base[utex_y >> 25];
  223.             if (p != PIXEL_CYAN)
  224.                 *start = p;
  225.             utex_y += tex_dy;
  226.             start -= fb_width;
  227.             }
  228.         }
  229.     else    // General (but slower) routine to handle any other power-of-2 texture size
  230.         {
  231.         utex_y <<= baseshift;
  232.         tex_dy <<= baseshift;
  233.         baseshift += 16;
  234.  
  235.         while (start >= end)
  236.             {
  237.             p = tex_base[utex_y >> baseshift];
  238.             if (p != PIXEL_CYAN)
  239.                 *start = p;
  240.             utex_y += tex_dy;
  241.             start -= fb_width;
  242.             }
  243.         }
  244.  
  245. }
  246.  
  247.  
  248.  
  249.  
  250. // The following are 16-bit versions of the inline drawing functions.
  251.  
  252.  
  253. inline void draw_wall_slice16(Pixel16 *start, Pixel16 *end, Pixel16 *tex_base,
  254.                             fixed tex_y, fixed tex_dy, int fb_width, 
  255.                             int baseshift)
  256. {
  257.     unsigned int utex_y;
  258.  
  259.     utex_y = (unsigned int) tex_y;
  260.  
  261.  
  262.     if (baseshift == 10)    // (2^(16-10), or 2^6, or 64 pixels)
  263.         {
  264.         utex_y <<= 10;
  265.         tex_dy <<= 10;
  266.  
  267.         while (start >= end)
  268.             {
  269.             *start = tex_base[utex_y >> 26];
  270.             utex_y += tex_dy;
  271.             start -= fb_width;
  272.             }
  273.         }
  274.     else if (baseshift == 9)    // (2^(16-9), or 2^7, or 128 pixels)
  275.         {
  276.         utex_y <<= 9;
  277.         tex_dy <<= 9;
  278.  
  279.         while (start >= end)
  280.             {
  281.             *start = tex_base[utex_y >> 25];
  282.             utex_y += tex_dy;
  283.             start -= fb_width;
  284.             }
  285.         }
  286.     else    // General (but slower) routine to handle any other power-of-2 texture size
  287.         {
  288.         utex_y <<= baseshift;
  289.         tex_dy <<= baseshift;
  290.         baseshift += 16;
  291.  
  292.         while (start >= end)
  293.             {
  294.             *start = tex_base[utex_y >> baseshift];
  295.             utex_y += tex_dy;
  296.             start -= fb_width;
  297.             }
  298.         }
  299. }
  300.  
  301.  
  302.  
  303.  
  304. inline void draw_floor_slice16(Pixel16 *start, Pixel16 *tex,
  305.                  fixed x, fixed y, fixed dx, fixed dy,
  306.                  short log2_tex_height, short npix)
  307. {
  308.     register Pixel temp;
  309.  
  310.  
  311.     if (log2_tex_height == 6)
  312.         {
  313.         /* width of 64 == 2^6 */
  314.         y <<= 6;
  315.         dy <<= 6;
  316.  
  317.         do {
  318.             x &= 0x3fffff;
  319.  
  320.            // No need to mask y--it rolls automatically *if* ints are 32 bits.
  321.            
  322.             if (*start == PIXEL_CYAN16)
  323.                 {
  324.                 temp = tex[FIXED_TO_INT((y & 0xfc00000) | x)];
  325.                 *start++ = temp;
  326.                 }
  327.             else
  328.                 *start++;
  329.             x += dx;
  330.             y += dy;
  331.             }
  332.         while (--npix > 0);
  333.         }
  334.     else if (log2_tex_height == 7)
  335.         {
  336.         y <<= 7;
  337.         dy <<= 7;
  338.  
  339.         do {
  340.             x &= 0x7fffff;
  341.  
  342.             if (*start == PIXEL_CYAN16)
  343.                 {
  344.                 temp = tex[FIXED_TO_INT((y & 0x3f800000) | x)];
  345.                 *start++ = temp;
  346.                 }
  347.             else
  348.                 *start++;
  349.             x += dx;
  350.             y += dy;
  351.             }
  352.         while (--npix > 0);
  353.         }
  354.     else    // General (but slower) routine to handle any other power-of-2 texture size
  355.         {
  356.         do {
  357.             x &= 0xffffffff >> (16 - log2_tex_height);
  358.             x &= 0x3fffff;
  359.  
  360.             /* No need to mask y--it rolls automatically *if* ints
  361.             **   are 32 bits.
  362.             */
  363.         
  364.             if (*start == PIXEL_CYAN16)
  365.                 {
  366.                 temp = tex[FIXED_TO_INT((y & (((1<<log2_tex_height)-1) <<(log2_tex_height+16))) | x)];
  367.                 *start++ = temp;
  368.                 }
  369.             else
  370.                 *start++;
  371.  
  372.             x += dx;
  373.             y += dy;
  374.             }
  375.         while (--npix > 0);
  376.         }
  377.  
  378. }
  379.  
  380.  
  381.  
  382.  
  383. inline void draw_transparent_slice16(Pixel16 *start, Pixel16 *end, Pixel16 *tex_base,
  384.                                 fixed tex_y, fixed tex_dy, int fb_width, int baseshift)
  385. {
  386.     unsigned int utex_y;
  387.     Pixel p;
  388.  
  389.  
  390.      /* As a speed optimization, tex_y and tex_dy are shifted left by several
  391.      **   bits so that tex_y can overflow correctly without explicit
  392.      **   and-masking.  For this to occur correctly, it is necessary to
  393.      **   make utex_y an unsigned quantity.  This is probably non-portable,
  394.      **   but should work with most architectures.
  395.      */
  396.     utex_y = (unsigned int) tex_y;
  397.  
  398.  
  399.     if (baseshift == 10)
  400.         {
  401.         utex_y <<= 10;
  402.         tex_dy <<= 10;
  403.  
  404.         while (start >= end)
  405.             {
  406.             p = tex_base[utex_y >> 26];
  407.             if (p != PIXEL_CYAN16)
  408.                 *start = p;
  409.             utex_y += tex_dy;
  410.             start -= fb_width;
  411.             }
  412.         }
  413.     else if (baseshift == 9)
  414.         {
  415.         utex_y <<= 9;
  416.         tex_dy <<= 9;
  417.  
  418.         while (start >= end)
  419.             {
  420.             p = tex_base[utex_y >> 25];
  421.             if (p != PIXEL_CYAN16)
  422.                 *start = p;
  423.             utex_y += tex_dy;
  424.             start -= fb_width;
  425.             }
  426.         }
  427.     else    // General (but slower) routine to handle any other power-of-2 texture size
  428.         {
  429.         utex_y <<= baseshift;
  430.         tex_dy <<= baseshift;
  431.         baseshift += 16;
  432.  
  433.         while (start >= end)
  434.             {
  435.             p = tex_base[utex_y >> baseshift];
  436.             if (p != PIXEL_CYAN16)
  437.                 *start = p;
  438.             utex_y += tex_dy;
  439.             start -= fb_width;
  440.             }
  441.         }
  442.  
  443. }
  444.